package edu.nyu.hps.assignment10;

public class Sudoku {

	int board[][], constraints[];
	Cell myBoard[][];

	public Sudoku() {
		board = new int[9][9];
		constraints = new int[2];
		myBoard = new Cell[9][9];
		for (int i = 0; i < board.length; i++) {
			for (int j = 0; j < board[i].length; j++) {
				Cell c = new Cell(board[i][j], i, j);
				myBoard[i][j] = c;
			}
		}
	}

	/**
	 * This method computes cells at the end of each game
	 */
	public void setBoardValues(int[][] board,Cell[][] myBoard) {
		for (int i = 0; i < board.length; i++) {
			for (int j = 0; j < board[i].length; j++) {

				Cell c = myBoard[i][j];
				c.value = board[i][j];

				if (c.value != 0) {
					c.taken = true;
					c.possibilities.clear();
				} else {
				}
			}
		}
		for (int i = 0; i < myBoard.length; i++) {
			for (int j = 0; j < myBoard[i].length; j++) {
				Cell c = myBoard[i][j];
				if (!c.taken) {
					setPossibilitiesFor(c);
				}
			}
		}
	}

	/**
	 * Computes the possibilities
	 */
	public void setPossibilitiesFor(Cell c) {
		if (!c.taken) {

			// Checking for columns
			for (int x = 0; x < 9; x++) {
				int val = myBoard[x][c.y].value;
				c.remove(val);
			}

			// Checking for rows
			for (int y = 0; y < 9; y++) {
				int val = myBoard[c.x][y].value;
				c.remove(val);
			}

			// Checking for blocks
			int xDash = c.x / 3;
			int yDash = c.y / 3;

			for (int x = xDash*3; x < (xDash*3 + 3); x++) {
				for (int y = yDash*3; y < (yDash*3 + 3); y++) {
					int val = myBoard[x][y].value;
					c.remove(val);
				}
			}
		}
	}

	public int getPossibleValues() {
		int count = 0;
		if(constraints[0]!=-1) {
			int i = constraints[0];
			for(int j=0;j< 9;j++) {
				Cell c = myBoard[i][j];
				if(!c.taken) {
					count = getPossibleCount(c);
				}
			}
		}
		else if(constraints[1]!=-1){
			int j = constraints[1];
			for(int i=0;i< 9;i++) {
				Cell c = myBoard[i][j];
				if(!c.taken) {
					count = getPossibleCount(c);
				}
			}
		}
		else {
			for(int i=0;i<9;i++) {
				for(int j=0;j<9;j++) {
					Cell c = myBoard[i][j];
					if(!c.taken) {
						count = getPossibleCount(c);
					}
				}
			}
		}
		
		return count;
	}
	
	public int getPossibleCount(Cell c) {
		if(c.possibilities.size()==0) {
			return 0;
		}
		else {
			int myCount = 0;
			for(int k=0;k<c.possibilities.size();k++) {
				int val = c.possibilities.get(k).intValue();
				int[][] newBoard = board.clone();
				board[c.x][c.y] = val;
				Cell[][] newMyBoard = myBoard.clone();
				setBoardValues(newBoard, newMyBoard);
				
				int[] oppConstraints = new int[2];
				if ((constraints[0] == -1 && constraints[1] == -1)
						|| (constraints[0] != -1 && constraints[1] == -1)) {
					oppConstraints[0] = -1;
					oppConstraints[1] = c.y;
				} else if (constraints[0] == -1 && constraints[1] != -1) {
					oppConstraints[0] = c.x;
					oppConstraints[1] = -1;
				}
				
				Moves m = new Moves(newMyBoard, oppConstraints, newBoard);
				myCount += m.returnScore() +1;
			}
			return myCount;
		}
	}
	public String play() {
		setBoardValues(board, myBoard);
		Moves m = new Moves(myBoard,constraints,board);
		String ans = m.returnMove();
		return ans;
	}

}
